package com.lhy.ltss.service;

import com.lhy.ltss.common.OrderStatusConst;
import com.lhy.ltss.common.UserRoleConst;
import com.lhy.ltss.dao.AddressDao;
import com.lhy.ltss.dao.FindDao;
import com.lhy.ltss.dao.OrderDao;
import com.lhy.ltss.entity.*;
import com.lhy.ltss.session.UserManage;
import com.sun.org.apache.xpath.internal.operations.Or;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @description:
 * @author: 李汇远
 */
@Service
@Transactional
public class OrderService {

    @Autowired
    AddressDao addressDao;

    @Autowired
    UserManage userManage;

    @Autowired
    OrderDao orderDao;

    @Autowired
    FindDao findDao;

    @Autowired
    ThreadPoolExecutor poolExecutor;

    // 手动开启事务需要的bean
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;

    // 添加地址
    public Integer addAddress(Address address){
        address.setUsername(userManage.getUsername());
        return  addressDao.add(address);
    }

    // 查询当前用户的地址
    public List<Address> findAddress(){
        return addressDao.find(userManage.getUsername());
    }

    // 查询指定id的地址
    public Address findAddressById(Integer id){
        return addressDao.findById(id);
    }

    // 删除地址
    public Integer removeAddress(Integer id){
        return addressDao.remove(id);
    }

    // 查询当前教师用户的未完成订单，分页
    public Page<Order> findOrderByUsername(Integer page){
        String username = userManage.getUsername();
        int totalPage = orderDao.countTodo(username) / 10;
        List<Order> list = orderDao.selectTodoByUsername(username, (page - 1) * 10);
        return new Page<>(page, totalPage + 1, list);
    }

    // 查询当前用户的历史订单，分页
    public Page<Order> findHistoryOrderByUsername(Integer page){
        String username = userManage.getUsername();
        int totalPage = orderDao.countHistory(username) / 10;
        List<Order> list = orderDao.selectHistoryByUsername(username, (page- 1) * 10);
        return new Page<>(page, totalPage + 1, list);
    }

    // 查询当前用户的未完成订单总数
    public Integer countTeacherTodo(){
        String username = userManage.getUsername();
        return orderDao.countTodo(username);
    }

    // 查询配送中的订单总数
    public Integer countTeacherDistribute(){
        String username = userManage.getUsername();
        return orderDao.count(username, OrderStatusConst.DISTRIBUTE);
    }

    // 统计教师订单信息
    public Map<String,Integer> statisticTeacherOrder() {
        String username = userManage.getUsername();
        Map<String,Integer> map = new HashMap<>();
        map.put("todo", orderDao.countTodo(username));
        map.put("distribute", orderDao.count(username, OrderStatusConst.DISTRIBUTE));
        map.put("finish", orderDao.count(username, OrderStatusConst.FINISH));
        return map;
    }

    // 统计 待处理 待找书订单：待登记订单： 待配送订单：
    public Map<String,Integer> statisticAdmin(){
        Map<String,Integer> map = new HashMap<>();
        String tmp = "'%s'";
        map.put("handler", orderDao.countOrderByStatusRange(String.format(tmp,OrderStatusConst.DEFAULT)));
        map.put("find", orderDao.countOrderByStatusRange(String.format(tmp, OrderStatusConst.FINDING)));
        map.put("register", orderDao.countOrderByStatusRange(String.format(tmp,OrderStatusConst.REGISTER)));
        map.put("distribute", orderDao.countOrderByStatusRange(String.format(tmp,OrderStatusConst.DISTRIBUTE)));
        return map;
    }

    // 获取订单信息
    public Page<MainOrder> findOrder(String username, String status, Integer page){
        username += "%";
        List<MainOrder> list = orderDao.findOrderByUsernameAndStatus(username, status, (page - 1) * 10);
        int totalPage = orderDao.countByUsernameAndStatus(username, status);
        totalPage = totalPage == 0 ? 1 : (totalPage / 10 + 1);
        return new Page<>(page, totalPage, list);
    }

    // 更新订单状态
    public Integer updateOrder(String status, Integer orderId){
        return orderDao.updateOrderStatus(status, orderId);
    }

    // 获取订单详情
    public List<Order> findOrderDetail(Integer orderId){
        return orderDao.findOrderDetailByOrderId(orderId);
    }

    // 更新订单详情状态
    public Integer updateOrderDetail(String status, Integer orderDetailId){
        return orderDao.updateOrderDetailStatus(status, orderDetailId);
    }

    // 分配订单给找书员
    public void findOrder(Integer id){
        poolExecutor.submit(()->{
            // 开启事务
            TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            try{
                // 查询子订单，并修改订单状态
                List<Order> list = orderDao.findOrderDetailByOrderId(id);
                orderDao.updateOrderStatus(OrderStatusConst.FINDING, id);
                // 遍历子订单，修改状态，匹配订单数最少的找书员，如果没有找书员则抛出异常，并添加到找书列表
                String username = findDao.getFinder();
                if (username == null)
                    throw new Exception("没有注册找书员");
                for (Order detail : list){
                    findDao.add(detail.getId(), username);
                    orderDao.updateOrderDetailStatus(OrderStatusConst.FINDING, detail.getId());
                }
                // 提交事务
                dataSourceTransactionManager.commit(transactionStatus);
            }catch (Exception e){
                e.printStackTrace();
                dataSourceTransactionManager.rollback(transactionStatus);
            }
        });
    }

    // 登记订单
    public void registerOrder(Integer id){
        orderDao.updateOrderStatus(OrderStatusConst.DISTRIBUTE, id);
        orderDao.registerOrderDetail(id);
    }

    // 确认配送的订单
    public void distributeOrderCheck(Integer id){
        orderDao.updateOrderStatus(OrderStatusConst.FINISH, id);
        orderDao.distributeOrderDetail(id);
    }

    // 下单
    public void makeOrder(int addressId, List<Book> books){
        // 使用线程池方式，异步下达订单
        final String username = userManage.getUsername();
        poolExecutor.submit(()->{
            // 开启事务
            TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            try{
                // 创建订单并初始化
                MainOrder mainOrder = new MainOrder();
                mainOrder.setAddress(addressId);
                Date curDate = Calendar.getInstance().getTime();
                mainOrder.setCreate(curDate);
                mainOrder.setStatus(OrderStatusConst.DEFAULT);
                mainOrder.setUsername(username);
                // 保存订单
                orderDao.addMainOrder(mainOrder);
                // 创建订单详情
                List<Order> orders = new LinkedList<>();
                for (Book book : books){
                    Order order = new Order();
                    order.setOrder(mainOrder.getId());
                    order.setBook_name(book.getBook_name());
                    order.setBook_editor(book.getBook_editor());
                    order.setBook_publish(book.getBook_publish());
                    order.setBook_index(book.getBook_index());
                    order.setStatus(OrderStatusConst.DEFAULT);
                    // 保存订单详情
                    orderDao.addOrder(order);
                }
                // 提交事务
                dataSourceTransactionManager.commit(transactionStatus);
            }catch (Exception e){
                e.printStackTrace();
                // 手动回滚
                dataSourceTransactionManager.rollback(transactionStatus);
            }
        });
    }

}
